/**
 * Created by asus on 2017/10/21.
 */
public class BTNode<T> {
    protected T element;
    protected BTNode<T> left,right;
    public BTNode(T element){
        this.element=element;
        left=right=null;
    }
    public T getElement(){
        return element;
    }
    public void setElement(T element){
        this.element=element;
    }
    public BTNode<T> getLeft(){
        return left;
    }
    public void setLeft(BTNode<T> left){
        this.left=left;
    }
    public BTNode<T> getRight(){
        return right;
    }
    public void setRight(BTNode<T> right){
        this.right=right;
    }
    public BTNode<T> find(T target){
        BTNode<T> result = null;
        if (element.equals(target))
            result=this;
        else {
            if (left!=null)
                result = left.find(target);
            if (result==null&&right==null)
                result = right.find(target);
        }
        return result;
    }
    public int count(){
        int result=1;
        if (left!=null)
            result+=left.count();
        if (right!=null)
            result+=right.count();
        return result;
    }
    public void inorder(ArrayIterator<T> iter){
        if (left!=null)
            left.inorder(iter);
        iter.add(element);
        if (right!=null)
            right.inorder(iter);
    }
    public void preorder(ArrayIterator<T> iter){
        iter.add(element);
        if (left!=null)
            left.preorder(iter);
        if (right!=null)
            right.preorder(iter);
    }
    public void postorder(ArrayIterator<T> iter){
        if(left!=null)
            left.postorder(iter);
        if (right!=null)
            right.postorder(iter);
        iter.add(element);
    }
    public BTNode<T> copy(){
        BTNode<T> newRoot = new BTNode<>(element);
        if (left!=null){
            newRoot.setLeft(left.copy());
        }
        if (right!=null){
            newRoot.setRight(right.copy());
        }
        return newRoot;
    }
}
